package org.jfbmonitor.view;

import java.awt.FontMetrics;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.sql.SQLException;
import java.sql.Time;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Timer;

import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.table.TableModel;
import javax.swing.JTextArea;

import org.jfbmonitor.beans.Attachment;
import org.jfbmonitor.dao.AttachmentDao;
import org.jfbmonitor.dao.DataBaseDao;
import org.jfbmonitor.beans.DataBase;
import org.jfbmonitor.beans.Transaction;
import org.jfbmonitor.dao.TransactionDao;
import org.jfbmonitor.dao.StatementDao;
import org.jfbmonitor.beans.Statement;
import org.jfbmonitor.language.Language;
import org.jfbmonitor.task.Task;
import org.jfbmonitor.view.attachment.AttachmentColumnModel;
import org.jfbmonitor.view.attachment.AttachmentTableModel;
import org.jfbmonitor.view.transaction.TransactionColumnModel;
import org.jfbmonitor.view.database.DataBaseColumnModel;
import org.jfbmonitor.view.database.DataBaseIOChart;
import org.jfbmonitor.view.database.DataBaseTableModel;
import org.jfbmonitor.view.transaction.TransactionTableModel;
import org.jfbmonitor.view.statement.StatementTableModel;
import org.jfbmonitor.view.statement.StatementColumnModel;
import org.jfree.data.time.RegularTimePeriod;


public class Monitor extends JFrame implements ActionListener, ItemListener {

	/**
	 * @author Randerson
	 */
	private static final long serialVersionUID = 1L;

	private JMenuBar menuBar;
	private JMenu menuMonitor;
	private JTabbedPane tabbedPane;

	private JPanel panelAttachment;
	private JPanel panelDataBase;
	private JPanel panelStatement;
	private JPanel panelTransaction;
    private JTextArea TextAreaStatement;
	private JScrollPane scrollTableAttachment;
    private JScrollPane scrollTableDataBase;
	private JScrollPane scrollTableTransaction;
    private JScrollPane scrollTableStatement;
    private JScrollPane Scrollsqlviewerpane;
	private JTable tableAttachment;
	private JTable tableTransaction;
    private JTable tableDataBase;
    private JTable tableStatement;
	private JPanel panelFilterAttachment;
    private JPanel panelFilterDataBase;
	private JPanel panelFilterTransaction;
    private JPanel panelSQlViewerStatement;
	private TableModel attachmentTableModel;
    private TableModel databaseTableModel;
	private TableModel transactionTableModel;
    private TableModel statementTableModel;
	private JCheckBoxMenuItem cbMenuItemFive;
	private JCheckBoxMenuItem cbMenuItemTen;
	private JCheckBoxMenuItem cbMenuItemFifteen;
	private JCheckBoxMenuItem cbMenuItemPaused;
	private JCheckBoxMenuItem cbMenuItemShowMonitorData;
	private JSeparator separatorSeconds;
	private JSeparator separatorRefresh;
	private JSeparator separatorShowMonitorData;
	private JMenuItem menuItemRefresh;
	private Timer timer;
	private int interval;
	private ButtonGroup btGroupSeconds;
	private JSplitPane splitPaneAttachment;
	private JSplitPane splitPaneTransaction;
    private JSplitPane splitPaneDataBase;
    private JSplitPane splitPaneStatement;
	private String attachmentCondition;
    private String transactionCondition;
    private String statementCondition;
    private DataBaseIOChart chartDataBase;



	private void initComponentsMenuMonitor() {
		menuMonitor = new JMenu();
		menuMonitor.setText(Language.getInstance().getProperties("MENU.MONITOR"));

		// Create buttons seconds
		btGroupSeconds = new ButtonGroup();
		cbMenuItemFive = new JCheckBoxMenuItem();
		cbMenuItemFive.setSelected(true);
		cbMenuItemFive.setText(Language.getInstance().getProperties("MENU.MONITOR.FIVESECOND"));
		cbMenuItemFive.addItemListener(this);
		btGroupSeconds.add(cbMenuItemFive);

		cbMenuItemTen = new JCheckBoxMenuItem();
		cbMenuItemTen.setSelected(false);
		cbMenuItemTen.setText(Language.getInstance().getProperties("MENU.MONITOR.TENSECOND"));
		cbMenuItemTen.addItemListener(this);
		btGroupSeconds.add(cbMenuItemTen);

		cbMenuItemFifteen = new JCheckBoxMenuItem();
		cbMenuItemFifteen.setSelected(false);
		cbMenuItemFifteen.setText(Language.getInstance().getProperties("MENU.MONITOR.FIFTEENSECOND"));
		cbMenuItemFifteen.addItemListener(this);
		btGroupSeconds.add(cbMenuItemFifteen);

		// Create menuItem refresh
		separatorSeconds = new JSeparator();

		menuItemRefresh = new JMenuItem();
		menuItemRefresh.setText("Start / Refresh");
		menuItemRefresh.setIcon(new javax.swing.ImageIcon(getClass().getResource("/org/jfbmonitor/view/icon/refresh.png")));
		menuItemRefresh.addActionListener(this);

		// Create CheckBoxMenuItem Paused
		cbMenuItemPaused = new JCheckBoxMenuItem();
		cbMenuItemPaused.setText(Language.getInstance().getProperties("MENU.MONITOR.PAUSED"));
		cbMenuItemPaused.addItemListener(this);

		// Create CheckBoxMenuItem Show Monitor Data
		cbMenuItemShowMonitorData = new JCheckBoxMenuItem();
		cbMenuItemShowMonitorData.setText(Language.getInstance().getProperties("MENU.MONITOR.SHOWMONITORDATA"));
		cbMenuItemShowMonitorData.setSelected(true);
		cbMenuItemShowMonitorData.addItemListener(this);

		separatorRefresh = new JSeparator();
		separatorShowMonitorData = new JSeparator();

		menuMonitor.add(cbMenuItemFive);
		menuMonitor.add(cbMenuItemTen);
		menuMonitor.add(cbMenuItemFifteen);
		menuMonitor.add(separatorSeconds);
		menuMonitor.add(menuItemRefresh);
		menuMonitor.add(separatorRefresh);
		menuMonitor.add(cbMenuItemPaused);
		menuMonitor.add(separatorShowMonitorData);
		menuMonitor.add(cbMenuItemShowMonitorData);
		menuBar.add(menuMonitor);
	}

	private void initComponentsTabbedAttachment() {
		getContentPane().add(tabbedPane, java.awt.BorderLayout.CENTER);

		scrollTableAttachment = new JScrollPane();
		tableAttachment = new JTable();
		tableAttachment.setAutoscrolls(true);
		scrollTableAttachment.setViewportView(tableAttachment);

		tableAttachment.setAutoCreateColumnsFromModel(false);
		FontMetrics fm = tableAttachment.getFontMetrics(tableAttachment.getFont());
		tableAttachment.setColumnModel(new AttachmentColumnModel(fm));

		panelAttachment = new JPanel();
		panelAttachment.setLayout(new java.awt.BorderLayout());
		panelAttachment.add(scrollTableAttachment, java.awt.BorderLayout.CENTER);
		panelFilterAttachment = new JPanel();

		panelFilterAttachment.setBorder(javax.swing.BorderFactory
				.createTitledBorder(Language.getInstance().getProperties(
						"MONITOR.FILTER")));

		// aqui foi adicionadado no teste
		splitPaneAttachment = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true,
				panelAttachment, panelFilterAttachment);

		splitPaneAttachment.setOneTouchExpandable(true);

		tabbedPane.addTab(Language.getInstance().getProperties(
				"TABBED.ATTACHMENT"), new javax.swing.ImageIcon(getClass()
				.getResource("/org/jfbmonitor/view/icon/connect.png")),
				splitPaneAttachment);

	}

	private void initComponentsTabbedDataBase() {
     	getContentPane().add(tabbedPane, java.awt.BorderLayout.CENTER);

		scrollTableDataBase = new JScrollPane();
		tableDataBase = new JTable();
		tableDataBase.setAutoscrolls(true);
		scrollTableDataBase.setViewportView(tableDataBase);
		
		JScrollPane scrollChartDataBase = new JScrollPane();
		chartDataBase = new DataBaseIOChart();
		chartDataBase.setAutoscrolls(true);
		scrollChartDataBase.setViewportView(chartDataBase.getGrafico());

		tableDataBase.setAutoCreateColumnsFromModel(false);
		FontMetrics fmDataB = tableDataBase.getFontMetrics(tableDataBase.getFont());
 		tableDataBase.setColumnModel(new DataBaseColumnModel(fmDataB));

		panelDataBase = new JPanel();
		panelDataBase.setLayout(new java.awt.BorderLayout());
		panelDataBase.add(scrollTableDataBase, java.awt.BorderLayout.WEST);
		panelDataBase.add(scrollChartDataBase, java.awt.BorderLayout.EAST);
        
        panelFilterDataBase = new JPanel();
		panelFilterDataBase.setBorder(javax.swing.BorderFactory.
                createTitledBorder(Language.getInstance().getProperties("MONITOR.FILTER")));

		splitPaneDataBase = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true,
				panelDataBase, panelFilterDataBase);

		tabbedPane.addTab(Language.getInstance().getProperties(
				"TABBED.DATABASE"), new javax.swing.ImageIcon(getClass()
				.getResource("/org/jfbmonitor/view/icon/database.png")),
				splitPaneDataBase);

	}

	private void initComponentsTabbedTransaction() {

		panelFilterTransaction = new JPanel();
		panelTransaction = new JPanel();
		scrollTableTransaction = new JScrollPane();
		tableTransaction = new JTable();
		tableTransaction.setAutoscrolls(true);
		scrollTableTransaction.setViewportView(tableTransaction);

		tableTransaction.setAutoCreateColumnsFromModel(false);
		FontMetrics fmTrans = tableTransaction.getFontMetrics(tableTransaction
				.getFont());
		tableTransaction.setColumnModel(new TransactionColumnModel(fmTrans));

		panelTransaction.setLayout(new java.awt.BorderLayout());
		panelTransaction.add(scrollTableTransaction,
				java.awt.BorderLayout.CENTER);

		panelFilterTransaction.setBorder(javax.swing.BorderFactory
				.createTitledBorder(Language.getInstance().getProperties(
						"MONITOR.FILTER")));
		splitPaneTransaction = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true,
				panelTransaction, panelFilterTransaction);
		splitPaneTransaction.setOneTouchExpandable(true);

		tabbedPane.addTab(Language.getInstance().getProperties(
				"TABBED.TRANSACTION"), new javax.swing.ImageIcon(getClass()
				.getResource("/org/jfbmonitor/view/icon/app.png")),
				splitPaneTransaction);

	}

	private void initComponentsTabbedStatement(){

        panelSQlViewerStatement = new JPanel();
		panelStatement = new JPanel();
		scrollTableStatement = new JScrollPane();
		tableStatement = new JTable();
		tableStatement.setAutoscrolls(true);
		scrollTableStatement.setViewportView(tableStatement);

		tableStatement.setAutoCreateColumnsFromModel(false);
		FontMetrics fmStat = tableStatement.getFontMetrics(tableStatement.getFont());
		tableStatement.setColumnModel(new StatementColumnModel(fmStat));

		panelStatement.setLayout(new java.awt.BorderLayout());
		panelStatement.add(scrollTableStatement,java.awt.BorderLayout.CENTER);

        Scrollsqlviewerpane = new JScrollPane();
		TextAreaStatement = new JTextArea();
        Scrollsqlviewerpane.setViewportView(TextAreaStatement);

        TextAreaStatement.setText("");

        panelSQlViewerStatement.setBorder(javax.swing.BorderFactory
				.createTitledBorder(Language.getInstance().getProperties(
						"MONITOR.FILTER")));

        panelSQlViewerStatement.setLayout(new java.awt.BorderLayout());
        panelSQlViewerStatement.add(Scrollsqlviewerpane);

		splitPaneStatement = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true,
				panelStatement, panelSQlViewerStatement);
		splitPaneStatement.setOneTouchExpandable(true);


		tabbedPane.addTab(Language.getInstance().getProperties(
		"TABBED.STATEMENT"), new javax.swing.ImageIcon(getClass()
		.getResource("/org/jfbmonitor/view/icon/script.png")),
		splitPaneStatement);
	}

	public Monitor() {

		setSize(Toolkit.getDefaultToolkit().getScreenSize().width, Toolkit
				.getDefaultToolkit().getScreenSize().height);

		// Create MenuBar
		menuBar = new JMenuBar();
		setJMenuBar(menuBar);

		initComponentsMenuMonitor();

		// Create TabbedPane
		tabbedPane = new JTabbedPane();

		initComponentsTabbedAttachment();
		initComponentsTabbedTransaction();
		initComponentsTabbedStatement();
        initComponentsTabbedDataBase();

		setDefaultCloseOperation(EXIT_ON_CLOSE);

        setTitle("jFBMonitor");

		setAttachmentCondition("");
        setTransactionCondition("");
        setStatementCondition("");

        setInterval(5000);
		adjustTimer(interval);

        timer.cancel();
	}

	public TableModel getAttachmentTableModel() {
		return attachmentTableModel;
	}

	public void setAttachmentTableModel(TableModel attachmentTableModel) {
		this.attachmentTableModel = attachmentTableModel;
		tableAttachment.setModel(attachmentTableModel);
	}

    public TableModel getDataBaseTableModel() {
		return databaseTableModel;
	}

	public void setDataBaseTableModel(TableModel databaseTableModel) {
		this.databaseTableModel = databaseTableModel;
		tableDataBase.setModel(databaseTableModel);
	}

	public TableModel getTransactionTableModel() {
		return transactionTableModel;
	}

	public void setTransactionTableModel(TableModel transactionTableModel) {
		this.transactionTableModel = transactionTableModel;
		tableTransaction.setModel(transactionTableModel);
	}

    public TableModel getStatementTableModel(){
        return statementTableModel;
    }

    public void setStatementTableModel(TableModel statementTableModel){
        this.statementTableModel = statementTableModel;
        tableStatement.setModel(statementTableModel);
    }

	@Override
	public void actionPerformed(ActionEvent obj) {
		// TODO Auto-generated method stub
		if (obj.getSource() == menuItemRefresh) {
			actionRefresh();
		}
	}

	@Override
	public void itemStateChanged(ItemEvent obj) {
		if (obj.getSource() == cbMenuItemFive) {
			if (cbMenuItemFive.isSelected()) {
				setInterval(5000);
				timer.cancel();
				adjustTimer(interval);
			}
		}
		if (obj.getSource() == cbMenuItemTen) {
			if (cbMenuItemTen.isSelected()) {
				setInterval(10000);
				timer.cancel();
				adjustTimer(interval);
			}
		}
		if (obj.getSource() == cbMenuItemFifteen) {
			if (cbMenuItemFifteen.isSelected()) {
				setInterval(15000);
				timer.cancel();
				adjustTimer(interval);
			}
		}
		if (obj.getSource() == cbMenuItemPaused) {
			if (cbMenuItemPaused.isSelected()) {
				timer.cancel();
			} else {
				adjustTimer(interval);
			}
		}
		if (obj.getSource() == cbMenuItemShowMonitorData) {
			if (cbMenuItemShowMonitorData.isSelected()) {
				attachmentCondition  = "";
                transactionCondition = "";
                statementCondition   = "";
			} else {
				attachmentCondition = "A.MON$ATTACHMENT_ID <> CURRENT_CONNECTION";
                transactionCondition = "A.MON$ATTACHMENT_ID <> CURRENT_CONNECTION";
                statementCondition = "A.MON$ATTACHMENT_ID <> CURRENT_CONNECTION";
			}
		}
	}

	private void actionRefresh() {
		List<Attachment> listAttachment;
        List<DataBase> listDataBase;
        List<Transaction> listTransaction;
        List<Statement> listStatement;
		try {
            //create the DAO object to set list that will be include to the grid
			AttachmentDao attachmentDao = new AttachmentDao();
			listAttachment = attachmentDao.getAll(attachmentCondition);
			setAttachmentTableModel(new AttachmentTableModel(listAttachment));

            DataBaseDao databaseDao = new DataBaseDao();
            listDataBase = databaseDao.getAll();
			setDataBaseTableModel(new DataBaseTableModel(listDataBase));

			StatementDao statementDao = new StatementDao();
            listStatement = statementDao.getAll(statementCondition);
            setStatementTableModel(new StatementTableModel(listStatement));
			
			TransactionDao transactionDao = new TransactionDao();
            listTransaction = transactionDao.getAll(transactionCondition);
            setTransactionTableModel(new TransactionTableModel(listTransaction));

            chartDataBase.addSeriesOldestActive( new Date().getSeconds(), listDataBase.get(0).getOldestActive());
            chartDataBase.addSeriesOldestTransaction(new Date().getSeconds(), listDataBase.get(0).getOldestTransaction());
            chartDataBase.addSeriesNextTransaction(new Date().getSeconds(), listDataBase.get(0).getNextTransaction());
            
			timer.cancel();
			adjustTimer(interval);


		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	private void adjustTimer(int interval) {
		timer = new Timer();
		timer.scheduleAtFixedRate(new Task(this), 0, interval);
	}

	public String getAttachmentCondition() {
		return attachmentCondition;
	}

	public void setAttachmentCondition(String attachmentCondition) {
		this.attachmentCondition = attachmentCondition;
	}

	public int getInterval() {
		return interval;
	}

	public void setInterval(int interval) {
		this.interval = interval;
	}

    public String getTransactionCondition() {
        return transactionCondition;
    }

    public void setTransactionCondition(String transactionCondicion) {
        this.transactionCondition = transactionCondicion;
    }

    public String getStatementCondition() {
        return statementCondition;
    }

    public void setStatementCondition(String statementCondition) {
        this.statementCondition = statementCondition;
    }

}
